package com.suray.attendance.common.dingding.service.impl;

import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.Common;
import com.suray.attendance.common.dingding.DingTalkClientUtils;
import com.suray.attendance.common.dingding.service.DingAccessTokenService;
import com.suray.attendance.common.utils.LoggerUtil;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

@CommonsLog
@Service
public class DingAccessTokenServiceImpl implements DingAccessTokenService {

    @Value("${dingding.appkey}")
    String appKey;
    @Value("${dingding.appsecret}")
    String appSecret;

    AccessToken accessToken;


    @Override
    public synchronized String getAccessToken() {
        try {
            Long dateTime = System.currentTimeMillis();
            if(accessToken == null || dateTime > accessToken.expiresIn) {
                evict();
                accessToken = login();
            }
            String re = accessToken.accessToken;
            return re;
        }catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            LoggerUtil.error("获取accessToken失败，异常结果："+_err.getMessage(),DingAccessTokenServiceImpl.class);
            if (!Common.empty(err.code) && !Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                log.error(err);
            }
            throw new RuntimeException("获取accessToken失败，异常结果："+_err.getMessage());
        }
    }

    public AccessToken login() {
        try {
            GetAccessTokenRequest request = new GetAccessTokenRequest();
            request.setAppKey(appKey);
            request.setAppSecret(appSecret);
            Long dateTime = System.currentTimeMillis();
            GetAccessTokenResponseBody rsp = DingTalkClientUtils.createOauthClient().getAccessToken(request).getBody();
            AccessToken accessToken = new AccessToken(rsp.getAccessToken(), dateTime + (rsp.getExpireIn() * 1000));
            return accessToken;
        } catch (TeaException err) {
            if (!Common.empty(err.code) && !Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!Common.empty(err.code) && !Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }
        }
        return null;
    }

    /**
     * 清除缓存
     */
    @CacheEvict(value="accessToken")
    public void evict() {
        accessToken = null;
    }

    private static class AccessToken{
        /**
         * 许可号
         */
        public String accessToken;
        /**
         * 失效时间
         */
        public Long expiresIn;

        public AccessToken(String accessToken, Long expiresIn) {
            this.accessToken = accessToken;
            this.expiresIn = expiresIn;
        }
    }

}
